package com.hnas.appLogin.web;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hnas.account.orm.Account;
import com.hnas.account.service.AccountService;
import com.hnas.api.dto.DTOResult;
import com.hnas.appLogin.dto.DTOLoginOutReceive;
import com.hnas.appLogin.dto.search.DTOLogin;
import com.hnas.appLogin.orm.AppSysLog;
import com.hnas.appLogin.service.AppSysLogService;
import com.hnas.appLogin.service.LoginService;
import com.hnas.appLogin.service.VerifyCodeService;
import com.hnas.appLogin.util.AppTypeConstants;
import com.hnas.appLogin.util.LoginConstants;
import com.hnas.common.interfacedsc.InterfaceDsc;
import com.hnas.common.returndto.LoginReturn;
import com.hnas.common.util.CommonUtils;
import com.hnas.common.util.ResultCode;
import com.hnas.core.util.DateUtil;
import com.hnas.core.util.StringUtil;

@Controller
@RequestMapping("/app/index")
public class LoginControl {

	@Value("#{component['wx_token_valid_time']}")
	private String wxTokenValidTime;

	private static Log log = LogFactory.getLog(LoginControl.class);

	private static ObjectMapper objectMapper = new ObjectMapper();

	@Autowired
	private AccountService accountService;

	@Autowired
	private LoginService loginService;

	@Autowired
	private VerifyCodeService verifyCodeService;

	@Autowired
	private AppSysLogService appSysLogService;

	/**
	 * 通过openid查找用户信息（免登陆）
	 * @param request
	 * @return
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "getAccountByOpenId", method = RequestMethod.POST)
	@ResponseBody
	public String getAccountByOpenId(HttpServletRequest request) {
		DTOResult dtoResult = new DTOResult();
		String sendData = "";
		try {
			sendData = request.getParameter("sendData");
			// 入参为空判断
			if (StringUtil.isEmpty(sendData)) {
				return CommonUtils.createResult(dtoResult, ResultCode.ERROR_10000, null);
			}
			JSONObject jo = (JSONObject) JSON.parse(sendData);
			String openId = jo.getString("openid");
			if (StringUtil.isEmpty(openId)) {
				return CommonUtils.createResult(dtoResult, ResultCode.ERROR_001, null);
			}
			// 通过openid查找账户信息
			Account account = accountService.findByOpenId(openId);
			if (null != account) {
				return loginReturn(account,dtoResult);
			}
			// 找不到用户信息
			return CommonUtils.createResult(dtoResult, ResultCode.ERROR_011, null);
		} catch (Exception e) {
			e.printStackTrace();
			// 日志记录
			log.info(DateUtil.dateTimeToString(new Date()) + "调用接口：" + InterfaceDsc.App_WXXNK_GetAccInfoByOpenid
					+ ",请求数据:入参为:" + sendData + "  出错:" + e);
			return CommonUtils.createResult(dtoResult, ResultCode.ERROR_002, null);
		} finally {
			// 日志记录
			log.info(DateUtil.dateTimeToString(new Date()) + "调用接口：" + InterfaceDsc.App_WXXNK_GetAccInfoByOpenid
					+ ",请求数据:入参为:" + sendData + "  返回参数:" + dtoResult);
		}
	}

	/**
	 * 通过账户ID查找账户信息
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "getAccountById", method = RequestMethod.POST)
	@ResponseBody
	public String getAccountById(HttpServletRequest request) {
		DTOResult dtoResult = new DTOResult();
		String sendData = "";
		try {
			sendData = request.getParameter("sendData");
			// 入参为空判断
			if (StringUtil.isEmpty(sendData)) {
				return CommonUtils.createResult(dtoResult, ResultCode.ERROR_10000, null);
			}
			
			JSONObject jo = (JSONObject) JSON.parse(sendData);
			String accountId = jo.getString("acc_id");
			
			if (StringUtil.isEmpty(accountId)) {
				return CommonUtils.createResult(dtoResult, ResultCode.ERROR_012, null);
			}
			// 通过账户ID查找账户信息
			Account account = accountService.findById(accountId);
			if (null != account) {
				return loginReturn(account,dtoResult);
			}
			// 找不到用户信息
			return CommonUtils.createResult(dtoResult, ResultCode.ERROR_011, null);
		} catch (Exception e) {
			e.printStackTrace();
			// 日志记录
			log.info(DateUtil.dateTimeToString(new Date()) + "调用接口：" + InterfaceDsc.APP_WXXNK_GetAccountById
					+ "请求数据，入参为:" + sendData + "  出错:" + e);
			return CommonUtils.createResult(dtoResult, ResultCode.ERROR_105, null);
		} finally {
			// 日志记录
			log.info(DateUtil.dateTimeToString(new Date()) + "调用接口：" + InterfaceDsc.APP_WXXNK_GetAccountById
					+ "请求数据，入参为:" + sendData + "  返回参数:" + dtoResult);
		}
	}
	
	/**
	 * 注销登录
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/logout", method = RequestMethod.POST)
	@ResponseBody
	public String logout(HttpServletRequest request) {
		DTOResult dtoResult = new DTOResult();
		String sendData = "";
		DTOLoginOutReceive dto = null;
		try {
			sendData = request.getParameter("sendData");
			// 入参为空判断
			if (StringUtil.isEmpty(sendData)) {
				return CommonUtils.createResult(dtoResult, ResultCode.ERROR_10000, null);
			}
			JSONObject jo = (JSONObject) JSON.parse(sendData);
			dto = new DTOLoginOutReceive();
			dto.setAccout_id(jo.getString("accout_id"));
			dto.setApp_type(jo.getString("app_type"));
			if (StringUtil.isEmpty(dto.getAccout_id())) {
				return CommonUtils.createResult(dtoResult, ResultCode.ERROR_012, null);
			}
			// 登录类型判断
			if (StringUtil.isEmpty(dto.getApp_type())) {
				return CommonUtils.createResult(dtoResult, ResultCode.ERROR_098, null);
			}
			// 通过账户ID查找账户信息
			Account account = accountService.findById(dto.getAccout_id());
			if (null != account) {
				
				//微信虚拟卡注销
                if (AppTypeConstants.WXXNK.equals(dto.getApp_type())) {
                	account.setWxToken(CommonUtils.getNewToken());
                	accountService.saveOrUpdate(account);
					return CommonUtils.createResult(dtoResult, ResultCode.SUCCESS, null);
				}
                
                // 其他应用注销
    			return CommonUtils.createResult(dtoResult, ResultCode.ERROR_100, null);
			}
			// 找不到用户信息
			return CommonUtils.createResult(dtoResult, ResultCode.ERROR_011, null);
		} catch (Exception e) {
			e.printStackTrace();
			// 日志记录
			log.info(DateUtil.dateTimeToString(new Date()) + "调用接口：" + InterfaceDsc.App_WXXNK_Logout
					+ ",请求数据:入参为:" + sendData + "  出错:" + e);
			return CommonUtils.createResult(dtoResult, ResultCode.ERROR_013, null);
		} finally {
			// 日志记录
			log.info(DateUtil.dateTimeToString(new Date()) + "调用接口：" + InterfaceDsc.App_WXXNK_Logout
					+ ",请求数据:入参为:" + sendData + "  返回参数:" + dtoResult);
		}
	}
	
	/** {"acc_id":"","token":"e1122e0199ed4fbb8de448fa9e062910","app_type":"2","openid":"v3Rs8PTLPmYCAzg9ZV7ANNk"}
	 *  {"username":"yangfan11","password":"yang11.....","phone_no":"","phone_type":"华为6X","app_type":"1","imei":"256666","openid":"","login_type":"0","verify_code":""}
	 * 登录
	 * @param dto
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public String login(HttpServletRequest request) {
		DTOResult dtoResult = new DTOResult();
		DTOLogin dto = null;
		String sendData = "";
		String custData = "";
		JSONObject custDataJson = null;
		try {
			Account account = null;
			sendData = request.getParameter("sendData");
			custData = request.getParameter("customData");
			// 入参为空判断
			if (StringUtil.isEmpty(sendData) || StringUtil.isEmpty(custData)) {
				return CommonUtils.createResult(dtoResult, ResultCode.ERROR_10000, null);
			}
			custDataJson = (JSONObject) JSON.parse(custData);
			dto = objectMapper.readValue(sendData, DTOLogin.class);
			String appid = custDataJson.getString("appid");
			// 登录类型判断
			if (StringUtil.isEmpty(dto.getApp_type())) {
				return CommonUtils.createResult(dtoResult, ResultCode.ERROR_098, null);
			}
			// 登录方式判断
			if (StringUtil.isEmpty(dto.getLogin_type())) {
				return CommonUtils.createResult(dtoResult, ResultCode.ERROR_008, null);
			}

			// 手机登录时校验手机号码和短信验证码是否为空
			if (LoginConstants.VERIFI_LOGIN.equals(dto.getLogin_type())) {
				if (StringUtil.isEmpty(dto.getPhone_no())) {
					return CommonUtils.createResult(dtoResult, ResultCode.ERROR_003, null);
				}
				if (StringUtil.isEmpty(dto.getVerify_code())) {
					return CommonUtils.createResult(dtoResult, ResultCode.ERROR_004, null);
				}
				// 1.检查验证码是否正确
				boolean result = verifyCodeService.checkVerifyCode(dto.getPhone_no(), dto.getVerify_code());
				if (!result) {
					return CommonUtils.createResult(dtoResult, ResultCode.ERROR_009, null);
				}
				// 2.根据手机号码查找用户是否存在
				account = accountService.findByPhoneNo(dto.getPhone_no());
			}

			// 2.微信虚拟卡登录
			if (AppTypeConstants.WXXNK.equals(dto.getApp_type())) {
				// 2.2 手机号码登录
				if (LoginConstants.VERIFI_LOGIN.equals(dto.getLogin_type())) {
					//判断openid为空
					if (StringUtil.isEmpty(dto.getOpenid())) {
						return CommonUtils.createResult(dtoResult, ResultCode.ERROR_001, null);
					}
					if (null != account) {// 登录成功
						String oprTime = DateUtil.dateTimeToString(new Date());
						// 对原来绑定该其他手机绑定的openid进行解绑
						accountService.unBindOpenid(dto.getOpenid());
						// 更新登录信息，如token值、token有效截止时间、openid
						account = setWxParams(request, dto, appid, account, oprTime);
						accountService.saveOrUpdate(account);
						// 登录成功后返回对应参数
						return loginReturn(account,dtoResult);
					} else {// 进入注册
						Account account2 = loginService.register(dto, appid,
								AppTypeConstants.WXXNK, request,null);
						// 注册并登录成功后返回对应参数
						return loginReturn(account2,dtoResult);
					}
				}
				// 2.3 其他登录方式
				return CommonUtils.createResult(dtoResult, ResultCode.ERROR_101, null);
			}
			// 其他应用登录
			return CommonUtils.createResult(dtoResult, ResultCode.ERROR_100, null);
		} catch (Exception e) {
			e.printStackTrace();
			log.info(DateUtil.dateTimeToString(new Date()) + "调用接口：" + InterfaceDsc.App_WXXNK_Login + ",请求数据:入参为:"
					+ sendData + " 出错:" + e);
			return CommonUtils.createResult(dtoResult, ResultCode.ERROR_016, null);
		} finally {
			// 日志记录
			log.info(DateUtil.dateTimeToString(new Date()) + "调用接口：" + InterfaceDsc.App_WXXNK_Login + ",请求数据:入参为:"
					+ sendData + "  返回参数:" + dtoResult);
		}
	}

	/**
	 * 设置微信虚拟卡新的属性值
	 * @param request
	 * @param dto
	 * @param appid
	 * @param account
	 * @param oprTime
	 * @return
	 */
	private Account setWxParams(HttpServletRequest request, DTOLogin dto, String appid, Account account,
			String oprTime) {
		account.setAppId(appid);
		account.setWxToken(CommonUtils.getNewToken());
		account.setWxTokenValidEndTime(CommonUtils.nowAddSeconds(Long.parseLong(wxTokenValidTime)));
		account.setAppType(AppTypeConstants.WXXNK);
		account.setCount((account.getCount() + 1));
		account.setLastLoginIP(request.getRemoteHost());
		account.setLastLoginTime(oprTime);
		account.setOpenId(dto.getOpenid());
		account.setUpdateTime(oprTime);
		account.setLoginType(dto.getLogin_type());
		return account;
	}

	/**
	 * 登录成功返回
	 * @param account
	 * @return
	 */
	public String loginReturn(Account account,DTOResult dtoResult) throws Exception {
		try {
			LoginReturn loginReturn = new LoginReturn();
			loginReturn.setAccout_id(account.getId());
			loginReturn.setLast_login_time(account.getLastLoginTime());
			if(AppTypeConstants.WXXNK.equals(account.getAppType())){
				loginReturn.setToken(account.getWxToken());
			}else{
				loginReturn.setToken(account.getAppToken());
			}
			loginReturn.setEmp_id(account.getEmpId());
			loginReturn.setEmp_name(account.getUserName());
			loginReturn.setPhone_no(account.getPhoneNo());
			return CommonUtils.createResult(dtoResult, ResultCode.SUCCESS, objectMapper.writeValueAsString(loginReturn));
		} catch (Exception e) {
			e.printStackTrace();
			return CommonUtils.createResult(dtoResult, ResultCode.ERROR_075, null);
		} 
	}
	
	public void saveAppLog(String ip, String content, String accId, String opType, String appId) {
		AppSysLog appSysLog = new AppSysLog();
		appSysLog.setId(CommonUtils.getUUID());
		appSysLog.setAccId(accId);
		appSysLog.setContent(content);
		appSysLog.setAppId(appId);
		appSysLog.setIp(ip);
		appSysLog.setOperateTime(DateUtil.dateTimeToString(new Date()));
		appSysLog.setOperateType(opType);
		appSysLogService.save(appSysLog);
	}
	
}
